/**
 * 播放管理器 Hook
 * 统一管理所有类型的播放内容（直播话术、用户互动、一键播报）
 */

import { useCallback, useRef, useEffect, useMemo } from 'react'
import { IPC_CHANNELS } from 'shared/ipcChannels'
import {
  PlaybackQueueManager,
  createQueueItem,
  type PlaybackQueueItem,
  type PlaybackContentType,
  type PlayMode,
  type RecycleItem,
} from '@/utils/playbackQueue'
import { createFrontendLogger } from '@/utils/logger'
import { useAIAssist } from './useAIAssist'
import { useAIChatStore } from './useAIChat'
import { useAccounts } from './useAccounts'

/**
 * 播放状态回调
 */
export interface PlaybackCallbacks {
  onPlayStart?: (item: PlaybackQueueItem) => void
  onPlayEnd?: (item: PlaybackQueueItem) => void
  onPlayError?: (item: PlaybackQueueItem, error: Error) => void
  onQueueEmpty?: () => void
}

/**
 * 播放管理器 Hook
 */
export function usePlaybackManager(callbacks?: PlaybackCallbacks) {
  const { currentAccountId } = useAccounts()
  const { config, contentRewrite, setPreviewQueue, setRecycleBin, setCurrentPlayingId } = useAIAssist()
  const { config: aiConfig, apiKeys: aiApiKeys, getActiveLiveStreamConfig } = useAIChatStore()
  const logger = useMemo(() => createFrontendLogger('播放管理器'), [])
  
  // 获取当前直播间配置
  const activeLiveStreamConfig = getActiveLiveStreamConfig()
  
  // 创建播放队列管理器实例（持久化）
  const managerRef = useRef<PlaybackQueueManager | null>(null)
  if (!managerRef.current) {
    const recycleConfig = config.playback?.recycle || { enable: false, probability: 0 }
    managerRef.current = new PlaybackQueueManager(recycleConfig)
  }
  const manager = managerRef.current
  
  // 播放状态
  const isPlayingRef = useRef(false)
  const currentIntervalTimerRef = useRef<NodeJS.Timeout | null>(null)
  
  /**
   * 更新回收站配置
   */
  useEffect(() => {
    manager.updateRecycleConfig(config.playback.recycle || { enable: false, probability: 0 })
  }, [config.playback.recycle, manager])
  
  /**
   * 同步队列到全局状态
   */
  const syncQueueToState = useCallback(() => {
    const queue = manager.getQueue()
    setPreviewQueue(queue)
  }, [manager, setPreviewQueue])
  
  /**
   * 同步回收站到全局状态
   */
  const syncRecycleBinToState = useCallback(() => {
    const bin = manager.getRecycleBin()
    setRecycleBin(bin)
  }, [manager, setRecycleBin])
  
  /**
   * 播放单个项目（语音合成+播放）
   */
  const playItem = useCallback(async (item: PlaybackQueueItem): Promise<void> => {
    logger.info(`🎵 开始播放 [${item.type}]: ${item.rewrittenContent.substring(0, 30)}...`)
    
    // 设置当前播放ID
    setCurrentPlayingId(item.id)
    callbacks?.onPlayStart?.(item)
    
    try {
      // 合成并播放
      await window.ipcRenderer.invoke(
        IPC_CHANNELS.tasks.aiAssist.synthesizeVoice,
        {
          text: item.rewrittenContent,
          voiceConfig: config,
        }
      )
      
      logger.success(`✅ 播放完成 [${item.type}]`)
      callbacks?.onPlayEnd?.(item)
    } catch (error) {
      logger.error(`❌ 播放失败: ${error instanceof Error ? error.message : String(error)}`)
      callbacks?.onPlayError?.(item, error instanceof Error ? error : new Error(String(error)))
      throw error
    } finally {
      setCurrentPlayingId(null)
    }
  }, [config, logger, setCurrentPlayingId, callbacks])
  
  /**
   * 计算间隔时间
   * 只有下一个项目是直播话术时，才需要间隔
   * 其他类型（用户互动、一键播报等）立即播放，不需要间隔
   */
  const calculateInterval = useCallback((nextType: PlaybackContentType | null): number => {
    if (nextType !== 'live_script') {
      return 0 // 下一个不是直播话术，立即播放
    }
    
    const { min, max } = config.playback.interval
    return Math.random() * (max - min) + min
  }, [config.playback.interval])
  
  /**
   * 播放下一个项目
   */
  const playNext = useCallback(async (): Promise<void> => {
    if (!isPlayingRef.current) {
      logger.info('播放已停止')
      return
    }
    
    // 检查队列是否为空
    if (manager.getQueueLength() === 0) {
      logger.info('队列为空，播放结束')
      isPlayingRef.current = false
      callbacks?.onQueueEmpty?.()
      return
    }
    
    // 从队列取出第一项
    const item = manager.dequeue()
    if (!item) {
      return
    }
    
    // 设置为当前播放项
    manager.setCurrentPlaying(item)
    
    try {
      // 播放
      await playItem(item)
      
      // 播放完成，移入回收站
      manager.completeCurrent()
      
      // 同步状态
      syncQueueToState()
      syncRecycleBinToState()
      
      // 根据下一个项目的类型计算间隔时间
      // 只有下一个是直播话术时才需要间隔
      const nextType = manager.getNextItemType()
      const intervalSeconds = calculateInterval(nextType)
      
      if (intervalSeconds > 0) {
        logger.info(`⏱️ 等待 ${intervalSeconds.toFixed(1)} 秒后播放下一条...`)
        
        // 清除旧的定时器
        if (currentIntervalTimerRef.current) {
          clearTimeout(currentIntervalTimerRef.current)
        }
        
        // 设置新的定时器
        currentIntervalTimerRef.current = setTimeout(() => {
          playNext()
        }, intervalSeconds * 1000)
      } else {
        // 立即播放下一条
        playNext()
      }
    } catch (error) {
      logger.error(`播放失败，继续下一条: ${error}`)
      // 即使失败也要继续播放下一条
      manager.completeCurrent()
      syncQueueToState()
      playNext()
    }
  }, [manager, playItem, calculateInterval, syncQueueToState, syncRecycleBinToState, logger, callbacks])
  
  /**
   * 开始播放
   */
  const startPlayback = useCallback(() => {
    if (isPlayingRef.current) {
      logger.warn('已经在播放中')
      return
    }
    
    if (manager.getQueueLength() === 0) {
      logger.warn('队列为空，无法开始播放')
      return
    }
    
    isPlayingRef.current = true
    logger.info('🎬 开始播放')
    playNext()
  }, [manager, playNext, logger])
  
  /**
   * 停止播放
   */
  const stopPlayback = useCallback(() => {
    if (!isPlayingRef.current) {
      return
    }
    
    isPlayingRef.current = false
    logger.info('⏸️ 停止播放')
    
    // 清除定时器
    if (currentIntervalTimerRef.current) {
      clearTimeout(currentIntervalTimerRef.current)
      currentIntervalTimerRef.current = null
    }
    
    // 清除当前播放项
    manager.setCurrentPlaying(null)
    
    // 停止音频播放（使用any类型绕过TypeScript检查）
    ;(window.ipcRenderer as any).send('tts:stop-audio')
  }, [logger, manager])
  
  /**
   * AI改写文本
   */
  const rewriteText = useCallback(async (originalText: string): Promise<string> => {
    const apiKey = aiApiKeys[aiConfig.provider]
    if (!apiKey) {
      throw new Error('请先在AI助手页面配置 API Key')
    }

    logger.info(`开始AI改写: ${originalText.substring(0, 20)}...`)

    // 构建改写提示词
    let systemPrompt = '你是一个专业的文案改写助手，擅长保持原文字数进行精准改写。'
    if (activeLiveStreamConfig) {
      if (activeLiveStreamConfig.role) {
        systemPrompt += `你的角色定位是：${activeLiveStreamConfig.role}。`
      }
      if (activeLiveStreamConfig.positivePrompt) {
        systemPrompt += `${activeLiveStreamConfig.positivePrompt}`
      }
      if (activeLiveStreamConfig.negativePrompt) {
        systemPrompt += `注意避免：${activeLiveStreamConfig.negativePrompt}`
      }
      if (activeLiveStreamConfig.productParams) {
        systemPrompt += `产品信息：${activeLiveStreamConfig.productParams}`
      }
    }

    const originalLength = originalText.length
    const minLength = Math.max(1, originalLength - 10)
    const maxLength = originalLength + 10
    
    const userPrompt = `请将以下直播话术进行改写，保持原意但用不同的表达方式。

原话术：${originalText}

要求：
1. 保持核心意思完全不变
2. 可以调整语序、替换同义词
3. 语气要自然、口语化
4. 字数控制在 ${minLength} 到 ${maxLength} 字之间
5. 直接输出改写后的文本，不要有任何解释说明`

    const messages = [
      { role: 'system', content: systemPrompt },
      { role: 'user', content: userPrompt },
    ]

    // customBaseURL暂时不使用，直接传undefined
    const customBaseURL = undefined

    try {
      const rewrittenText = await window.ipcRenderer.invoke(
        IPC_CHANNELS.tasks.aiChat.normalChat,
        {
          provider: aiConfig.provider,
          model: aiConfig.model,
          apiKey,
          messages,
          customBaseURL,
        }
      )

      if (!rewrittenText) {
        throw new Error('AI返回内容为空')
      }

      logger.success(`AI改写成功: ${rewrittenText}`)
      return rewrittenText.trim()
    } catch (error) {
      logger.error(`AI改写失败: ${error instanceof Error ? error.message : String(error)}`)
      throw error
    }
  }, [aiConfig, aiApiKeys, activeLiveStreamConfig, logger])
  
  /**
   * 添加直播话术到队列
   * 支持回收站重播逻辑
   */
  const addLiveScript = useCallback(async (
    originalContent: string,
    shouldRewrite: boolean = true
  ): Promise<void> => {
    // 检查是否应该从回收站抽取
    if (manager.shouldDrawFromRecycleBin()) {
      const recycleItem = manager.drawFromRecycleBin()
      if (recycleItem) {
        logger.info(`♻️ 从回收站抽取话术: ${recycleItem.rewrittenContent.substring(0, 30)}...`)
        
        // 将回收站项目转换为队列项目
        const queueItem: PlaybackQueueItem = {
          id: `recycle-${Date.now()}`,
          type: 'live_script',
          originalContent: recycleItem.originalContent,
          rewrittenContent: recycleItem.rewrittenContent,
          audioData: recycleItem.audioData,
          timestamp: Date.now(),
        }
        
        manager.enqueue(queueItem)
        syncQueueToState()
        return
      }
    }
    
    // 正常添加新话术
    let rewrittenContent = originalContent
    
    if (shouldRewrite) {
      try {
        logger.info(`🤖 AI改写话术中...`)
        rewrittenContent = await rewriteText(originalContent)
        logger.success(`✅ AI改写完成: ${rewrittenContent.substring(0, 30)}...`)
      } catch (error) {
        logger.error(`AI改写失败，使用原文: ${error}`)
        rewrittenContent = originalContent
      }
    }
    
    const item = createQueueItem('live_script', originalContent, rewrittenContent)
    manager.enqueue(item)
    syncQueueToState()
    logger.info(`➕ 添加直播话术到队列 (队列长度: ${manager.getQueueLength()})`)
  }, [manager, rewriteText, syncQueueToState, logger])
  
  /**
   * 添加用户互动到队列
   * 根据全局配置的playMode决定播放模式
   */
  const addUserInteraction = useCallback(async (content: string): Promise<void> => {
    const item = createQueueItem('user_interaction', content, content)
    
    // 获取用户互动配置的播放模式
    const playMode = config.playback?.userInteraction?.playMode || 'next'
    
    logger.info(`📢 添加用户互动 [模式: ${playMode}]: ${content.substring(0, 30)}...`)
    
    // 根据播放模式插入队列
    manager.handleQuickBroadcast(item, playMode)
    syncQueueToState()
    
    // 如果是立即模式且正在播放，停止当前音频并触发下一个播放
    if (playMode === 'immediate' && isPlayingRef.current) {
      logger.info('⏸️ 立即模式：停止当前音频，触发队首播放')
      ;(window.ipcRenderer as any).send('tts:stop-audio')
      // tts:stop-audio 会触发 handleStopAudio -> tts:play-complete
      // 这会让 playItem 完成，然后 playNext 会自动播放队首的新项
    } else if (!isPlayingRef.current) {
      // 如果当前没有在播放，立即开始播放
      startPlayback()
    }
  }, [manager, config.playback, syncQueueToState, startPlayback, logger])
  
  /**
   * 添加一键播报到队列
   * 支持两种模式：立即播放（打断当前）或等待当前播放完成
   * playMode必须由调用方显式指定（通常从UI界面的选择器中获取）
   */
  const addQuickBroadcast = useCallback(async (
    content: string,
    playMode: PlayMode = 'next'
  ): Promise<void> => {
    const item = createQueueItem('quick_broadcast', content, content)
    
    logger.info(`📢 添加一键播报 [模式: ${playMode}]: ${content.substring(0, 30)}...`)
    
    // 根据播放模式插入队列
    manager.handleQuickBroadcast(item, playMode)
    syncQueueToState()
    
    // 如果是立即模式且正在播放，停止当前音频并触发下一个播放
    if (playMode === 'immediate' && isPlayingRef.current) {
      logger.info('⏸️ 立即模式：停止当前音频，触发队首播放')
      ;(window.ipcRenderer as any).send('tts:stop-audio')
      // tts:stop-audio 会触发 handleStopAudio -> tts:play-complete
      // 这会让 playItem 完成，然后 playNext 会自动播放队首的新项
    } else if (!isPlayingRef.current) {
      // 如果当前没有在播放，立即开始播放
      startPlayback()
    }
  }, [manager, syncQueueToState, startPlayback, logger])
  
  /**
   * 清空队列
   */
  const clearQueue = useCallback(() => {
    manager.clearQueue()
    syncQueueToState()
    logger.info('🗑️ 队列已清空')
  }, [manager, syncQueueToState, logger])
  
  /**
   * 清空回收站
   */
  const clearRecycleBin = useCallback(() => {
    manager.clearRecycleBin()
    syncRecycleBinToState()
    logger.info('🗑️ 回收站已清空')
  }, [manager, syncRecycleBinToState, logger])
  
  /**
   * 获取队列统计信息
   */
  const getQueueStats = useCallback(() => {
    return manager.getQueueStats()
  }, [manager])
  
  /**
   * 获取队列长度
   */
  const getQueueLength = useCallback(() => {
    return manager.getQueueLength()
  }, [manager])
  
  /**
   * 获取回收站内容
   */
  const getRecycleBin = useCallback((): RecycleItem[] => {
    return manager.getRecycleBin()
  }, [manager])
  
  /**
   * 获取是否正在播放
   */
  const isPlaying = useCallback(() => {
    return isPlayingRef.current
  }, [])
  
  // 组件卸载时清理
  useEffect(() => {
    return () => {
      stopPlayback()
    }
  }, [stopPlayback])
  
  return {
    // 播放控制
    startPlayback,
    stopPlayback,
    isPlaying,
    
    // 队列操作
    addLiveScript,
    addUserInteraction,
    addQuickBroadcast,
    clearQueue,
    getQueueLength,
    getQueueStats,
    
    // 回收站操作
    clearRecycleBin,
    getRecycleBin,
  }
}
